package com.uduew.sjd

import android.app.Activity
import android.app.Application
import android.content.Context
import android.os.Bundle
import android.widget.TextView
import androidx.appcompat.widget.AppCompatTextView
import cat.ereza.customactivityoncrash.config.CaocConfig
import com.drake.statelayout.StateConfig
import com.drake.statelayout.handler.FadeStateChangedHandler
import com.google.gson.reflect.TypeToken
import com.google.gson.stream.JsonToken
import com.hjq.bar.TitleBar
import com.hjq.bar.style.LightBarStyle
import com.hjq.gson.factory.GsonFactory
import com.hjq.gson.factory.ParseExceptionCallback
import com.hjq.http.EasyConfig
import com.hjq.http.config.IRequestInterceptor
import com.hjq.http.config.IRequestServer
import com.hjq.http.model.ContentType
import com.hjq.http.model.HttpHeaders
import com.hjq.http.model.HttpParams
import com.hjq.http.request.HttpRequest
import com.kongzue.dialogx.DialogX
import com.uduew.sjd.bean.IucdBean
import com.uduew.sjd.config.AppConfig
import com.uduew.sjd.config.Const
import com.uduew.sjd.exception.RequestHandler
import com.uduew.sjd.server.ReleaseServer
import com.uduew.sjd.ui.form.FormActivity
import com.uduew.sjd.utils.AesUtils
import com.uduew.sjd.utils.HttpsUtils
import com.uduew.sjd.utils.Utils
import com.uduew.utils.AppUtils
import com.uduew.utils.DeviceUtils
import com.uduew.utils.GsonUtils
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody
import okhttp3.Response
import okhttp3.ResponseBody
import org.json.JSONObject
import java.util.concurrent.TimeUnit


class App : Application() {
    private var currentActivityName: String? = null
    private var activityCount = 0

    companion object {
        private var context: Context? = null

        fun get(): Context? = context
    }


    override fun onCreate() {
        super.onCreate()
        context = this
        Utils.init(this)

        registerActivityLifecycleCallbacks(object : ActivityLifecycleCallbacks {
            override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
                activityCount++
            }

            override fun onActivityStarted(p0: Activity) {
            }

            override fun onActivityDestroyed(activity: Activity) {
                activityCount--
                if (activityCount == 0) {
                }
            }

            override fun onActivityResumed(activity: Activity) {
                currentActivityName = activity::class.java.name
                if (activity::class.java.name != SplashActivity::class.java.name) {
                    AppConfig.mConfigs.currentActivity().set(activity::class.java.name)
                }
            }

            override fun onActivityPaused(p0: Activity) {
            }

            override fun onActivityStopped(p0: Activity) {
            }

            override fun onActivitySaveInstanceState(
                p0: Activity,
                p1: Bundle
            ) {
            }
        })

        initHttp()
        DialogX.init(this)
        initTitleBar()
        Utils.init(this)
        StateConfig.apply {
            emptyLayout = R.layout.layout_empty
            errorLayout = R.layout.layout_error
            loadingLayout = R.layout.layout_loading
            stateChangedHandler = FadeStateChangedHandler()
            setRetryIds(R.id.msg, R.id.iv, R.id.refresh)
        }
        initCrash()
    }

    private fun initCrash() {
        CaocConfig.Builder.create()
            .backgroundMode(CaocConfig.BACKGROUND_MODE_SILENT) //default: CaocConfig.BACKGROUND_MODE_SHOW_CUSTOM
            .enabled(true) //default: true
            .showErrorDetails(true) //default: true
            .showRestartButton(true) //default: true
            .logErrorOnRestart(true) //default: true
            .trackActivities(true) //default: false
            .minTimeBetweenCrashesMs(2000) //default: 3000
            .errorDrawable(R.mipmap.app_logo).apply() //default: bug image

    }

    private fun initTitleBar() {
        TitleBar.setDefaultStyle(object : LightBarStyle() {
            override fun newTitleView(context: Context): TextView {
                return AppCompatTextView(context)
            }

            override fun newLeftView(context: Context): TextView {
                return AppCompatTextView(context)
            }

            override fun newRightView(context: Context): TextView {
                return AppCompatTextView(context)
            }
        })
    }

    fun initHttp() {
        // 设置 Json 解析容错监听 com.uduew.sjd
        GsonFactory.setParseExceptionCallback(object : ParseExceptionCallback {
            private fun handlerGsonParseException(message: String?) {
//                require(!BuildConfig.DEBUG) {
//                    message!!
//                }
//                CrashReport.postCatchedException(IllegalArgumentException(message))
            }

            override fun onParseObjectException(
                typeToken: TypeToken<*>?,
                fieldName: String?,
                jsonToken: JsonToken?
            ) {
                handlerGsonParseException("解析对象析异常：$typeToken#$fieldName，后台返回的类型为：$jsonToken");
            }

            override fun onParseListItemException(
                typeToken: TypeToken<*>?,
                fieldName: String?,
                listItemJsonToken: JsonToken?
            ) {
                handlerGsonParseException("解析 List 异常：$typeToken#$fieldName，后台返回的条目类型为：$listItemJsonToken");
            }

            override fun onParseMapItemException(
                typeToken: TypeToken<*>?,
                fieldName: String?,
                mapItemKey: String?,
                mapItemJsonToken: JsonToken?
            ) {
                handlerGsonParseException("解析 Map 异常：$typeToken#$fieldName，mapItemKey = $mapItemKey，后台返回的条目类型为：$mapItemJsonToken");
            }
        })

        var server: IRequestServer = ReleaseServer()
        var sslParams: HttpsUtils.SSLParams = HttpsUtils.getSslSocketFactory(null, null, null)
        val okHttpClient = OkHttpClient.Builder()
            .connectTimeout(15L, TimeUnit.SECONDS) // 连接超时
            .readTimeout(15L, TimeUnit.SECONDS)    // 读取超时
            .writeTimeout(15L, TimeUnit.SECONDS)   // 写入超时
//            .sslSocketFactory(sslParams.sSLSocketFactory, sslParams.trustManager)
//            .hostnameVerifier(HostnameVerifier { hostname: String?, session: SSLSession? -> true })
            .build()

        EasyConfig.with(okHttpClient)
            // 是否打印日志
            .setLogEnabled(true)
            // 设置服务器配置（必须设置）
            .setServer(server)
            // 设置请求处理策略（必须设置）
            .setHandler(RequestHandler(this))
            .setInterceptor(object : IRequestInterceptor {

                override fun interceptRequest(
                    httpRequest: HttpRequest<*>, request: Request
                ): Request {
                    try {
                        if (request.body == null || request.body.toString().isBlank()) {
                            return super.interceptRequest(httpRequest, request)
                        }
                        var body = request.body.toString()
                        val encrypt = AesUtils.encrypt(JSONObject(body).toString())
                        return request.newBuilder()
                            .post(RequestBody.create(ContentType.JSON, encrypt)).build()
                    } catch (e: Exception) {
                        e.printStackTrace()
                        return super.interceptRequest(httpRequest, request)
                    }
                }

                override fun interceptResponse(
                    httpRequest: HttpRequest<*>?,
                    response: Response?
                ): Response {

                    try {
                        if (response?.body == null) {
                            return super.interceptResponse(httpRequest, response)
                        }
                        val body = response.body!!.string()
                        val decryptStr = AesUtils.decrypt(body)
                        val newResponseBody = ResponseBody.create(
                            response.body?.contentType(),
                            decryptStr
                        )
                        return response.newBuilder()
                            .body(newResponseBody)
                            .build()
                    } catch (e: Exception) {
                        e.printStackTrace()
                        return super.interceptResponse(httpRequest, response)
                    }

                    return super.interceptResponse(httpRequest, response)
                }

                override fun interceptArguments(
                    httpRequest: HttpRequest<*>,
                    params: HttpParams,
                    headers: HttpHeaders
                ) {
                    val appId = Const.APPID
                    val json = GsonUtils.toJson(
                        IucdBean(
                            AppUtils.getAppVersionCode().toString(),
                            AppUtils.getAppVersionName(),
                            DeviceUtils.getAndroidID(),
                            AppConfig.gaid
                        )
                    )
                    val encryptedJson = AesUtils.encrypt(json)
                    val iucd = "$appId$encryptedJson"
                    headers.put("iucd", iucd)
                    val auth = AppConfig.mConfigs.token().get()
                    if (auth.isNotEmpty()) {
                        headers.put("Auth", auth)
                    }
                }
            })
            .setRetryTime(2000)
            .setRetryCount(2)
            .into()
    }


}